import { WSClient } from '../core/ws-client';


export class BusinessService {
    private wsClient: WSClient;
    private defaultTimeout = 15000; // 默认超时时间：15秒

    constructor(client: WSClient) {
        this.wsClient = client;
    }

    /**
     * 订阅指数K线数据
     * @param candleType K线周期，例如：'30m', '1D', '1W'等
     * @param instId 现货指数，如 'BTC-USD'
     * @param onCandleUpdate 当接收到K线数据更新时调用的回调函数
     * @param timeout 可选：超时时间（毫秒）
     * @returns Promise，在订阅成功或失败时解析
     */
    public subscribeCandle(
        candleType: string,
        instId: string,
        onCandleUpdate: (data: [string, string, string, string, string, string][]) => void,
        timeout: number = this.defaultTimeout
    ): Promise<void> {
        return new Promise((resolve, reject) => {
            // 确保WebSocket已连接
            if (!this.wsClient.isConnected()) {
                reject(new Error("WebSocket is not connected"));
                return;
            }

            // 构建完整的channel名称
            // 对于合约K线使用candle而不是index-candle
            const channel = `candle${candleType}`;

            // 注册回调函数，处理K线数据的消息
            const eventName = `${channel}:${instId}`;

            // 创建数据回调包装器，第一次收到数据也视为订阅成功
            let isResolved = false;
            const onDataReceived = (data: any) => {
                // 调用原始回调
                onCandleUpdate(data);

                // 如果尚未解析Promise，则解析
                if (!isResolved) {
                    console.log(`✅ 收到${channel}:${instId}的首条数据，确认订阅成功`);
                    isResolved = true;
                    clearTimeout(subscribeTimeout);
                    this.wsClient.off('subscribeSuccess', subscribeSuccessHandler);
                    this.wsClient.off('error', errorHandler);
                    resolve();
                }
            };
            this.wsClient.on(eventName, onDataReceived);

            // 设置超时
            const subscribeTimeout = setTimeout(() => {
                if (!isResolved) {
                    this.wsClient.off('subscribeSuccess', subscribeSuccessHandler);
                    this.wsClient.off('error', errorHandler);
                    // 不要移除数据监听器，因为即使超时，以后可能还会收到数据
                    reject(new Error(`Subscribe to ${channel} timeout after ${timeout}ms`));
                }
            }, timeout);

            // 监听订阅成功事件
            const subscribeSuccessHandler = (response: any) => {
                // 添加调试日志
                console.log('收到订阅响应:', JSON.stringify(response));

                // 检查是否包含正确的频道和交易对
                if (response.event === 'subscribe' &&
                    response.arg?.channel === channel &&
                    response.arg?.instId === instId) {
                    console.log(`✅ 成功订阅${channel}:${instId}`);

                    // 标记为已解析，避免重复解析
                    if (!isResolved) {
                        isResolved = true;
                        clearTimeout(subscribeTimeout);
                        this.wsClient.off('error', errorHandler);
                        resolve();
                    }
                }
            };

            // 监听错误事件
            const errorHandler = (err: any) => {
                if (!isResolved && (err.message?.includes(channel) || err.code)) {
                    isResolved = true;
                    clearTimeout(subscribeTimeout);
                    reject(err);
                }
            };

            this.wsClient.once('subscribeSuccess', subscribeSuccessHandler);
            this.wsClient.once('error', errorHandler);

            // 发送订阅请求
            const subscribeSuccess = this.wsClient.subscribe(channel, instId);
            if (!subscribeSuccess) {
                isResolved = true;
                clearTimeout(subscribeTimeout);
                this.wsClient.off('subscribeSuccess', subscribeSuccessHandler);
                this.wsClient.off('error', errorHandler);
                reject(new Error("Failed to send subscription request"));
            }
        });
    }

    /**
     * 取消订阅指数K线数据
     * @param candleType K线周期，例如：'30m', '1D', '1W'等
     * @param instId 现货指数，如 'BTC-USD'
     * @param timeout 可选：超时时间（毫秒）
     * @param forceClose 可选：是否强制关闭，不等待取消订阅响应
     * @returns Promise，在取消订阅成功或失败时解析
     */
    public unsubscribeCandle(
        candleType: string,
        instId: string,
        timeout: number = this.defaultTimeout,
        forceClose: boolean = false
    ): Promise<void> {
        return new Promise((resolve, reject) => {
            // 构建完整的channel名称
            const channel = `candle${candleType}`;
            
            // 移除相关的事件监听器，无论成功与否都先清理
            const eventName = `${channel}:${instId}`;
            console.log(`🧹 清理${eventName}的事件监听器`);
            this.wsClient.removeAllListeners(eventName);
            
            // 如果是强制关闭模式，则直接返回成功
            if (forceClose) {
                console.log(`🔌 强制关闭模式：跳过取消订阅流程，直接关闭连接`);
                resolve();
                return;
            }
            
            console.log(`⬇️ 发送取消订阅请求: ${channel}`);

            // 设置超时
            const unsubscribeTimeout = setTimeout(() => {
                console.log(`⚠️ 取消订阅${channel}超时，强制移除监听器并关闭`);
                this.wsClient.off('unsubscribeSuccess', unsubscribeSuccessHandler);
                this.wsClient.off('error', errorHandler);
                
                // 即使超时也解析Promise
                console.log(`⚠️ 已强制移除${channel}:${instId}的所有监听器`);
                resolve();
            }, timeout);

            // 监听取消订阅成功事件
            const unsubscribeSuccessHandler = (response: any) => {
                // 添加调试日志
                console.log('收到取消订阅响应:', JSON.stringify(response));
                
                // 检查是否包含正确的频道和交易对，注意event应该是unsubscribe
                if (response.event === 'unsubscribe' &&
                    response.arg?.channel === channel &&
                    response.arg?.instId === instId) {
                    
                    console.log(`✅ 成功取消订阅${channel}:${instId}`);
                    clearTimeout(unsubscribeTimeout);
                    resolve();
                }
            };

            // 监听错误事件
            const errorHandler = (err: any) => {
                console.error(`❌ 取消订阅出错:`, err);
                clearTimeout(unsubscribeTimeout);
                if (err.message?.includes(channel) || err.code) {
                    reject(err);
                }
            };

            this.wsClient.once('unsubscribeSuccess', unsubscribeSuccessHandler);
            this.wsClient.once('error', errorHandler);

            // 发送取消订阅请求
            const unsubscribeSuccess = this.wsClient.unsubscribe(channel, instId);
            if (!unsubscribeSuccess) {
                clearTimeout(unsubscribeTimeout);
                this.wsClient.off('unsubscribeSuccess', unsubscribeSuccessHandler);
                this.wsClient.off('error', errorHandler);
                reject(new Error("Failed to send unsubscription request"));
            }
        });
    }

} 